The ImageList control is most often used as a container for images and icons that are employed by other controls, such as TreeView, ListView, TabStrip, and ImageCombo controls. For this reason, it makes sense to describe it before any other controls. The ImageList control is invisible at run time, and to display one of the images it contains you must draw it on a form, a PictureBox control, or an Image control, or associate it with another control.
Using the ImageList control as a repository for images that are then used by other controls offers a number of advantages. Without this control, in fact, you would have to load images from disk at run time using a LoadPicture function, which slows down execution and increases the number of files to be distributed with your program, or an array of Image controls, which slows down form loading. It's much easier and more efficient to load all the images in the ImageList control at design time and then refer to them from the other controls or in source code.
The ImageList control exposes a ListImages collection, which in turn contains a number of ListImage objects. Each ListImage item holds an individual image. As with any collection, an individual ListImage object can be referenced through its numerical index or its string key (if it has one). Each ListImage object can hold an image in one of the following graphic formats: bitmap (.bmp), icon (.ico), cursor (.cur), JPEG (.jpg), or GIF (.gif). The latter two formats weren't supported by the ImageList control distributed with Visual Basic 5.
Adding images at design-time is easy. After you place an ImageList control on a form, right-click on it, select the Properties command from the pop-up menu, and switch to the Images tab, as shown in Figure 10-3. All you have to do now is click on the Insert Picture button and pick up your images from disk. You should associate a string key with each image so that you can refer to it correctly later, even if you add or remove other images in the future (which would affect its numerical index). Of course, all string keys must be unique in the collection. You can also specify a string for the Tag property of an image, for example, if you want to provide a textual description of the image or any other information associated with this image. Visual Basic never directly uses this property, so you're free to store any string data in it.
Figure 10-3. The Images tab of the Properties window of an ImageList control.
Images added to the ListImages collection can be of any size, with a caveat: If you're going to use these images inside another common control, all the images after the first one will be resized and stretched to reflect the size of the first image added to the control. This isn't an issue if you're going to display these images on a form, a PictureBox control, or an Image control.
If the ImageList control doesn't contain any images, you can set the size you want the images to be in the General tab of the Properties dialog box. Trying to do this when the control already contains one or more ListImage items raises an error.
Adding images at run time requires you to use the Add method of the ListImages collection, the syntax of which is the following:
Add([Index], [Key], [Picture]) As ListImage |
If you omit the Index argument, you add the new image at the end of the collection. The following code creates a new ListImage item and associates it with a bitmap loaded from disk:
Dim li As ListImage Set li = ImageList1.ListImages.Add(, "Cut", _ LoadPicture("d:\bitmaps\cut.bmp")) |
You don't need to assign the result value of the Add method to a ListImage object unless you want to assign a string to the Tag property of the object just created. Even in that case, you can do without an explicit variable:
With ImageList1.ListImages.Add(, "Cut", LoadPicture("d:\bitmaps\cut.bmp")) .Tag = "The Cut icon" End With |
You can remove individual ListImage objects (added either at design time or at run time) by using the Remove method of the ListImages collection.
' You can use a numerical index or a string key ' to remove the associated image. ImageList1.ListImages.Remove "Cut" |
You can also remove all the images in one operation by using the collection's Clear method:
' Remove all images. ImageList1.ListImages.Clear |
You can learn the size of the images currently stored in the control by using the ImageList's ImageWidth and ImageHeight properties. These properties are in pixels and can be written to only if the ListImages collection is empty; after you add the first image, they become read-only properties.
If you associate an ImageList control with another common control, you usually don't have to worry about extracting and showing individual images because everything is done automatically for you. But if you want to manually display or print images, you have to learn how to use a few properties and methods from the ImageList control and its ListImage dependent objects.
Each ListImage object exposes a Picture property, which lets you extract the image and assign it to another control, typically a PictureBox or Image control:
Set Picture1.Picture = ImageList1.ListImages("Cut").Picture |
In general, you can use the Picture property of a ListImage object whenever you would use the Picture property of a PictureBox or an Image control, as in the following example:
' Save an image to a disk file. SavePicture ImageList1.ListImages("Cut").Picture, "C:\cut.bmp" ' Display an image on the current form, zooming it by a factor ' of 4 along the X-axis, and 8 along the Y-axis. With ImageList1 PaintPicture .ListImages("Cut").Picture, 0, 0, _ ScaleX(.ImageWidth, vbPixels) * 4, ScaleY(.ImageHeight, vbPixels) * 8 End With |
Using the PaintPicture method, you can display any ListImage object on a form or in a PictureBox control, or you can print it to the Printer object. For more information about the PaintPicture method, see Chapter 2.
ListImage objects also expose an ExtractIcon method, which creates an icon out of the image and returns it to the caller. You can therefore use this method whenever an icon is expected, as in this code:
Form1.MouseIcon = ImageList1.ListImages("Pointer").ExtractIcon |
Unlike standard collections, keys in the ListImages collection are dealt with in a case-sensitive way. In other words, "Pointer" and "pointer" are assumed to be different items.
The ImageList control has a MaskColor property whose value determines the color that should be considered transparent when you're performing graphical operations on individual ListImage objects or when you're displaying images inside other controls. By default, this is the gray color (&HC0C0C0), but you can change it both at design time in the Color tab of the Properties dialog box and at run time via code.
When a graphical operation is performed, none of the pixels in the image that are the color defined by MaskColor are transferred. To actually display transparent images, however, you must ensure that the UseMaskColor property is set to True, which is its default value. You can modify this value in the General tab of the Properties dialog box or at run time via code:
' Make white the transparent color. ImageList1.MaskColor = vbWhite ImageList1.UseMaskColor = True |
ListImage objects support the Draw method, which has the following syntax:
Draw hDC, [x], [y], [Style] |
where hDC is the handle of a device context (typically the value returned by the hDC property of a form, a PictureBox control, or the Printer object) and x and y are the coordinates in pixels where the image should be displayed in the target object. Style is one of the following values: 0-imlNormal (default, draw the image without any change), 1-imlTransparent (use the MaskColor property to account for transparent areas), 2-imlSelected (draw the image dithered with the system highlight color), or 3-imlFocus (as imlSelected, but create a hatched effect to indicate that the image has the focus):
' Show an image in the upper left corner of a PictureBox control. ImageList1.ListImages("Cut").Draw Picture1.hDC, 0, 0 |
The ImageList control also includes the ability to create composite images by overlaying two individual images held in ListImage objects. This can be accomplished using the Overlay method. Figure 10-4 shows two individual images and then what you can get by overlaying the second one on the first one:
PaintPicture ImageList1.ListImages(1).Picture, 0, 10, 64, 64 PaintPicture ImageList1.ListImages(2).Picture, 100, 10, 64, 64 PaintPicture ImageList1.Overlay(1, 2), 200, 10, 64, 64 |
Figure 10-4. The effect of the Overlay method.
The Overlay method implicitly uses the MaskColor property to determine which color is to be considered as the transparent color, so you must ensure that the UseMaskColor property is set to True.